#include "CmdUtil.h"
#include <QStandardPaths>
#include <QDebug>
// CmdUtil::CmdUtil()  {}


void CmdUtil::parseCommandLineWithSpaceAndParam(const QString &commandLine, QString &programPath, QStringList &arguments) {
    // 使用正则表达式匹配引号内的部分（路径）和引号外的部分（参数）
    QRegularExpression re("\"([^\"]+)\"|(\\S+)");
    QRegularExpressionMatchIterator it = re.globalMatch(commandLine);

    bool isFirst = true;
    while (it.hasNext()) {
        QRegularExpressionMatch match = it.next();
        if (match.captured(1).length() > 0) {
            // 匹配到引号内的部分（路径）
            if (isFirst) {
                programPath = match.captured(1);
                isFirst = false;
            } else {
                arguments << match.captured(1);
            }
        } else if (match.captured(2).length() > 0) {
            // 匹配到引号外的部分（参数）
            arguments << match.captured(2);
        }
    }
}

QString CmdUtil::checkPath(const QString &path) {
    QFileInfo fileInfo(path);

    if (fileInfo.exists()) {
        if (fileInfo.isFile() || fileInfo.isDir()) {
            return path;
        }
    }

    return "-1";
}


QString CmdUtil::parseCommandAtSymbolWithPath(const QString &path, QString &programPath, QStringList &arguments)
{
    // 获取当前程序的路径
    QString currentPath = QCoreApplication::applicationDirPath();

    // 检查路径中是否包含"@"符号
    if (path.contains("@")) {
        // 替换"@"符号为当前程序的路径
        QString newPath = path;
        newPath.replace("@.", currentPath).replace("\\","/");
        int exePos = newPath.indexOf(".exe");
        programPath = newPath.left(exePos+4);
        QString argumentStr = newPath.right(newPath.length() - exePos-5);
        arguments = argumentStr.split(" ");
        if("-1" == checkPath(programPath)){
            QMessageBox::information(NULL, "入参检查", QString("parseCommandAtSymbolWithPath输入参数不正确: %1").arg(newPath));
        }
        return newPath;
    } else {
        // 如果路径中没有"@"符号，则返回原路径
        return path;
    }
}
QString CmdUtil::parsePathWithSpace(const QString &path)
{
    QString str = path;
    // QString path = "C:\\Program Files\\ToDesk\\ToDesk.exe";
    QString strpath = str.replace("\\","/");
    if(strpath.contains(" "))
    {
        str = QString("\"%1\"").arg(strpath);
    }
    else
    {
        str = strpath;
    }

    return str;
}

// 获取可执行文件路径
QString CmdUtil::getExecutableInSysPath(const QString& input) {
    QStringList systemPaths = {
        "C:\\Windows\\System32\\",
        "C:\\Windows\\SysWOW64\\"
    };

    QString fileName = input;
    if (!fileName.endsWith(".exe")) {
        fileName += ".exe";
    }

    foreach (const QString& path, systemPaths) {
        QString fullPath = path + fileName;
        if (QFile::exists(fullPath)) {
            return QDir::toNativeSeparators(fullPath);
        }
    }

    return QString(); // 文件不存在
}
// 获取可执行文件路径
QString CmdUtil::getExecutablePath(const QString& input) {
    int exePos = input.lastIndexOf(".exe");
    QStringList systemPaths = {
        "C:\\Windows\\System32\\",
        "C:\\Windows\\SysWOW64\\"
    };
    if (exePos == -1) {
        // QString sysPath = getExecutableInSysPath(input);//在系统路径下寻找是否存在
        // return sysPath; // 没有找到.exe
        return input;
    }

    QString path = input.left(exePos + 4); // 包含.exe
    if (QFile::exists(path)) {
        return path;
    } else {
        return input; // 路径无效
    }
}

// 获取参数列表
QStringList CmdUtil::getParameters(const QString& input) {
    int exePos = input.lastIndexOf(".exe");
    if (exePos == -1) {
        return QStringList(); // 没有找到.exe
    }

    QString paramsPart = input.mid(exePos + 4).trimmed();
    QStringList parameters = paramsPart.split(QRegExp("\\s+"), Qt::SkipEmptyParts);

    return parameters;
}

QString CmdUtil::getSystemUserName()
{
    QString username = QStandardPaths::standardLocations(QStandardPaths::HomeLocation).at(0).section('/', -1);
    qDebug() << "Username: " << username;
    QString username2 = QDir::home().dirName();
    qDebug() << "Username2: " << username2;
    return username;
}

QString CmdUtil::getSendToDirectory() {
    QString path = "C:/Users/baoqi/AppData/Roaming/ZdRun";
    QString parentPath = path.section('/', 0, -2);

    qDebug() << "Parent Path:" << parentPath;
    // 获取当前用户的 'SendTo' 目录
    // 这个目录通常在 Windows 中存在于用户的"发送到"菜单项下
    QString sendToDirPath = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
    QString sendToPath = QStandardPaths::writableLocation(QStandardPaths::AppDataLocation);
    QDir dir(sendToPath);
    if (dir.cdUp()) {
        sendToDirPath = dir.absolutePath() + QLatin1String("/Microsoft/Windows/SendTo");
        qDebug() << "SendTo Path:" << sendToDirPath;
    } else {
        qDebug() << "Failed to cdUp.";
    }

    return sendToDirPath;
}

#ifdef Q_OS_WIN
#include <QThread>
#include <tlhelp32.h>
#endif

void sendSignalToProcess(qint64 pid, int signal) {
#ifdef Q_OS_UNIX
    if (kill(pid, signal) == 0) {
        qDebug() << "Signal sent successfully to PID:" << pid;
    } else {
        qDebug() << "Failed to send signal to PID:" << pid;
    }
#elif defined(Q_OS_WIN)
    HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, FALSE, pid);
    if (hProcess != NULL) {
        if (TerminateProcess(hProcess, 0)) {
            qDebug() << "Process terminated successfully with PID:" << pid;
        } else {
            qDebug() << "Failed to terminate process with PID:" << pid;
        }
        CloseHandle(hProcess);
    } else {
        qDebug() << "Failed to open process with PID:" << pid;
    }
#endif
}
void CmdUtil::checkAndKillProcess(){
    // 使用共享内存来检查是否已经有进程在运行
    QSharedMemory sharedMemory("myApp_instance");
    if (!sharedMemory.create(1)) {
        // 如果共享内存创建失败，说明已经有进程在运行
        qDebug() << "Another instance of myApp is already running.";

        // 获取当前运行的进程的PID
        QProcess process;
        process.start("pidof", QStringList() << "zdRun");
        process.waitForFinished();
        QString output = process.readAllStandardOutput();
        qint64 pid = output.trimmed().toLongLong();

        if (pid > 0) {
            // 发送SIGTERM信号关闭进程
            sendSignalToProcess(pid, SIGTERM);

            // 等待一段时间确保进程关闭
            QThread::sleep(2);
        }
    }

    // 创建新的共享内存，表示新的进程正在运行
    sharedMemory.create(1);
}
